home *** CD-ROM | disk | FTP | other *** search
/ PC Media 23 / PC MEDIA CD23.iso / share / prog / bestl232 / !best004.c < prev    next >
C/C++ Source or Header  |  1994-04-18  |  17KB  |  412 lines

  1. /*==========================================================================
  2.  *
  3.  *  !BEST004.C                                        Sunday, April 17, 1994
  4.  *
  5.  *  .INI file routines
  6.  *  supplementary source file 4 for The BESTLibrary
  7.  *
  8.  *  Authored independently by George Vanous
  9.  *
  10.  *==========================================================================*/
  11.  
  12.  
  13. /* ------------------------------------------------------------------------ */
  14. /* ----------------------------  INCLUDE FILES  --------------------------- */
  15.  
  16. #include <dir.h>
  17. #include <dos.h>
  18. #include <alloc.h>
  19. #include <stdlib.h>
  20. #include "!bestlib.h"                  // include !BESTLIB.H in compilation
  21.  
  22. /* ------------------------------------------------------------------------ */
  23. /* ------------------------------  CONSTANTS  ----------------------------- */
  24.  
  25. /* used in procedure "ini_get_error" */
  26. #define BOOLEAN  0
  27. #define COLOR    1
  28. #define NUMBER   2
  29. #define POSITION 3
  30. #define ROWS     4
  31. #define STATE    5
  32. #define STRING   6
  33.  
  34. /* ------------------------------------------------------------------------ */
  35. /* ---------------------------  ERROR MESSAGES  --------------------------- */
  36.  
  37. #define ERR03 "\nI cannot open the initialization file -- I need this file to continue.\n\n"
  38. #define ERR04 "\nIt seems the initialization file is incorrect\n\nI do not know this color:  %s\n\nThis color is located here:\n%s\n\nThe colors I know are:  BLACK  BLUE  GREEN  CYAN  RED  MAGENTA  BROWN  LIGHTGREYDARKGREY  LIGHTBLUE  LIGHTGREEN  LIGHTCYAN  LIGHTRED  LIGHTMAGENT  YELLOW  WHITE\n"
  39. #define ERR05 "\nI believe the initialization file is incorrect\n\nThere is an invalid text string located here:\n%s\n\nThe offensive string is:  %s\n\nA valid string must be enclosed within quotation marks:  \"This string is OK!\"\n\nPlease remedy this problem.\n\n"
  40. #define ERR06 "\nI have found something incorrect in the initialization file\n\nThere is a section header missing from section:  %s\n\nI can not find this header:  %s\n\nPlease type it in.\n\n"
  41. #define ERR07 "\nThere is a problem with the initialization file\n\nI have located an open section\n\nI can not find this section terminator:  %s\n\nPlease input it.\n\n"
  42. #define ERR08 "\nI think something needs to be added to the initialization file\n\nI am missing an important option from this section:  %s\n\nCan you please insert this option:  %s\n\n"
  43. #define ERR09 "\nI cannot seem to understand one part of the initialization file\n\nI think an equality symbol, =, is missing from this section:\n%s\n\nI can not locate the = symbol for this option:  %s\n\nCan you please input it for me?\n\n"
  44. #define ERR10 "\nMaybe you can help me understand the initialization file\n\nThe problem lies in this section:\n%s\n\nThe parameter I am having trouble with is:  %s\n\nI think it can only be TRUE or FALSE -- can you please correct this problem?\n\n"
  45. #define ERR11 "\nThere seems to be an invalid number in the initialization file\n\nThe offensive number lies in this section:\n%s\n\nThe number I do not recognize is:  %s\n\nPlease try to correct this problem.\n\n"
  46. #define ERR12 "\nI am having difficulty understanding the initialization file\n\nMy question comes from this section:\n%s\n\nI do not know what is meant by this parameter:  %s\n\nI expected it to be either ON, OFF, or UNMODIFY -- can you help me?\n\n"
  47. #define ERR13 "\nThe initialization file must be in error\n\nI do not understand this screen location: %s\n\nIt is located in this section:\n%s\n\nI only understand these two screen positions:  TOP  BOTTOM\n\nPlease correct this problem and try again.\n\n"
  48. #define ERR14 "\nI think there is something that needs correcting in the initialization file\n\nI can only display 25 or 50 rows per screen, but in the section:\n%s\n\nI am asked to display %s rows.\n\nPlease input one of these values:  25, 50, or UNMODIFY.  Thank you.\n\n"
  49. #define ERR15 "\nI cannot find the file %s -- it was requested in the initialization file\n\nThis is the section that asked for the file:\n%s\n\nEither this file is not in the current directory or it is misspelled.\n\n"
  50.  
  51. /* ------------------------------------------------------------------------ */
  52. /* -------------------------  FUNCTION PROTOTYPES  ------------------------ */
  53.  
  54. void ini_get_error(char *section, char *str, word *ptr, byte type);
  55. char *ini_verify_format(char *section, char *section_title,
  56.                         char *option, word *ptr);
  57.  
  58. /* ------------------------------------------------------------------------ */
  59.  
  60.  
  61. /*----------------------------------------------------------------------------
  62.  * Translate the boolean word "TRUE" or "FALSE" into boolean TRUE or FALSE.
  63.  *
  64.  * "section"       - section text
  65.  * "section_title" - section title to read from
  66.  * "option"        - option to read from
  67.  *
  68.  * RETURNS:
  69.  * = TRUE if found string "TRUE"
  70.  * = FALSE if found string "FALSE"
  71.  */
  72. boolean ini_get_boolean(char *section, char *section_title, char *option)
  73. {
  74.   shortint value;                      // return value
  75.   char *str;                           // parameter
  76.   word  ptr[2];                        // two generic offset pointers
  77.  
  78.   str = ini_verify_format(section, section_title, option, ptr);
  79.  
  80.   if ((value = con_str_to_bool(str)) == -1)
  81.     ini_get_error(section, str, ptr, BOOLEAN);
  82.  
  83.   return( (boolean)value );
  84. }
  85.  
  86. /*----------------------------------------------------------------------------
  87.  * Translate a color name into its numerical equivalent.
  88.  *
  89.  * "section"       - section text
  90.  * "section_title" - section title to read from
  91.  * "option"        - option to read from
  92.  *
  93.  * RETURNS:
  94.  * = numerical equivalent of color name
  95.  */
  96. byte ini_get_color(char *section, char *section_title, char *option)
  97. {
  98.   shortint value;                      // return value
  99.   char *str;                           // parameter
  100.   word  ptr[2];                        // two generic offset pointers
  101.  
  102.   str = ini_verify_format(section, section_title, option, ptr);
  103.  
  104.   if ((value = con_str_to_color(str)) == -1)
  105.     ini_get_error(section, str, ptr, COLOR);
  106.  
  107.   return( (byte)value );
  108. }
  109.  
  110. /*----------------------------------------------------------------------------
  111.  * Display the offending parameter in the initialization file and exit to DOS
  112.  *   with the appropriate ERRORLEVEL.
  113.  *
  114.  * "section" - section text
  115.  * "str"     - parameter in question
  116.  * "ptr"     - two offset pointers
  117.  * "type"    - type of error
  118.  */
  119. void ini_get_error(char *section, char *str, word *ptr, byte type)
  120. {
  121.   char error[1000];                    // ample space for error message
  122.  
  123.   // isolate the section containing the error
  124.   *(section+ptr[0] + scan_byte(section+ptr[0], LF, NULL, FORWARD)-1) = NULL;
  125.  
  126.   // display the correct error message
  127.   switch (type) {
  128.     case BOOLEAN  : sprintf(error, ERR10, section+ptr[1], str            ); break;
  129.     case COLOR    : sprintf(error, ERR04, str,            section+ptr[1] ); break;
  130.     case NUMBER   : sprintf(error, ERR11, section+ptr[1], str            ); break;
  131.     case POSITION : sprintf(error, ERR13, str,            section+ptr[1] ); break;
  132.     case ROWS     : sprintf(error, ERR14, section+ptr[1], str            ); break;
  133.     case STATE    : sprintf(error, ERR12, section+ptr[1], str            ); break;
  134.     case STRING   : sprintf(error, ERR05, section+ptr[1], str            );
  135.   }
  136.   fprintf(stderr, error);
  137.   beep(); exit(3);
  138. }
  139.  
  140. /*----------------------------------------------------------------------------
  141.  * Translate an ASCII representation of a number into its numerical equivalent.
  142.  *
  143.  * "section"       - section text
  144.  * "section_title" - section title to read from
  145.  * "option"        - option to read from
  146.  *
  147.  * RETURNS:
  148.  * = numerical representation of number string
  149.  */
  150. int ini_get_number(char *section, char *section_title, char *option)
  151. {
  152.   char *str;                           // parameter
  153.   word  ptr[2];                        // two generic offset pointers
  154.  
  155.   str = ini_verify_format(section, section_title, option, ptr);
  156.  
  157.   if (!is_number_dec(str))
  158.     ini_get_error(section, str, ptr, NUMBER);
  159.  
  160.   return( atoi(str) );
  161. }
  162.  
  163. /*----------------------------------------------------------------------------
  164.  * Translate the screen position "TOP" or "BOTTOM" to the screen row number
  165.  *   (taking into account a possible 50-line text mode).
  166.  *
  167.  * "section"       - section text
  168.  * "section_title" - section title to read from
  169.  * "option"        - option to read from
  170.  *
  171.  * RETURNS:
  172.  * = screen row number
  173.  */
  174. int ini_get_position(char *section, char *section_title, char *option)
  175. {
  176.   char *str;                           // parameter
  177.   word  ptr[2];                        // two generic offset pointers
  178.  
  179.   str = ini_verify_format(section, section_title, option, ptr);
  180.  
  181.   str_case_up(str);
  182.   if (!str_cmp(str, "TOP"))
  183.     return( 0 );
  184.   if (str_cmp(str, "BOTTOM"))
  185.     ini_get_error(section, str, ptr, POSITION);
  186.  
  187.   return( txt_rows() );
  188. }
  189.  
  190. /*----------------------------------------------------------------------------
  191.  * Translate the number of rows per screen page "25", "50", or "UNMODIFY",
  192.  *   into the numerical equivalent.
  193.  *
  194.  * "section"       - section text
  195.  * "section_title" - section title to read from
  196.  * "option"        - option to read from
  197.  *
  198.  * RETURNS:
  199.  * = rows per screen page
  200.  */
  201. int ini_get_rows(char *section, char *section_title, char *option)
  202. {
  203.   char *str;                           // parameter
  204.   word num,                            // generic word
  205.        ptr[2];                         // two generic offset pointers
  206.  
  207.   str = ini_verify_format(section, section_title, option, ptr);
  208.  
  209.   if ((num = atoi(str)) == 25 || num == 50)
  210.     return( num-1 );
  211.  
  212.   str_case_up(str);
  213.   if (str_cmp(str, "UNMODIFY"))
  214.     ini_get_error(section, str, ptr, ROWS);
  215.  
  216.   return( txt_rows() );
  217. }
  218.  
  219. /*----------------------------------------------------------------------------
  220.  * Translate the keyboard state "ON", "OFF", or "UNMODIFY" into the numerical
  221.  *   equivalent.
  222.  *
  223.  * "section"       - section text
  224.  * "section_title" - section title to read from
  225.  * "option"        - option to read from
  226.  *
  227.  * RETURNS:
  228.  * = 0 - OFF
  229.  * = 1 - ON
  230.  * = 2 - UNMODIFY
  231.  */
  232. byte ini_get_state(char *section, char *section_title, char *option)
  233. {
  234.   char *str;                           // parameter
  235.   word ptr[2];                         // two generic offset pointers
  236.  
  237.   str = ini_verify_format(section, section_title, option, ptr);
  238.  
  239.   str_case_up(str);
  240.   if (!str_cmp(str, "OFF"))
  241.     return( 0 );
  242.   if (!str_cmp(str, "ON"))
  243.     return( 1 );
  244.   if (str_cmp(str, "UNMODIFY"))
  245.     ini_get_error(section, str, ptr, STATE);
  246.   return( 2 );
  247. }
  248.  
  249. /*----------------------------------------------------------------------------
  250.  * Translate a text string surrounded by quotes into a text string not
  251.  *   surrounded by quotes.
  252.  *
  253.  * "section"       - section text
  254.  * "section_title" - section title to read from
  255.  * "option"        - option to read from
  256.  *
  257.  * RETURNS:
  258.  * = pointer to quote-less string
  259.  */
  260. char *ini_get_text(char *section, char *section_title, char *option)
  261. {
  262.   char *str,                           // parameter
  263.        *str2;                          // temporary string space
  264.   word index,                          // generic character index
  265.        ptr[2];                         // two generic offset pointers
  266.  
  267.   str = ini_verify_format(section, section_title, option, ptr);
  268.  
  269.   // verify the text is surrounded by quotes
  270.   if (*str != '"' || str_right(str, 1) != '"')
  271.     ini_get_error(section, str, ptr, STRING);
  272.  
  273.   // remove the quotes and keep just the text
  274.   index = str_len(str)-2;              // remove two quotes
  275.   str2 = malloc(index+1);              // allocate memory for text + NULL
  276.   mem_copy(str2, str+1, index);        // make a copy of the text
  277.   str2[index] = NULL;                  // terminate string
  278.   return( str2 );
  279. }
  280.  
  281. /*----------------------------------------------------------------------------
  282.  * Translate the response "YES" or "NO" into the boolean TRUE or FALSE.
  283.  *
  284.  * "section"       - section text
  285.  * "section_title" - section title to read from
  286.  * "option"        - option to read from
  287.  *
  288.  * RETURNS:
  289.  * = TRUE  - YES
  290.  * = FALSE - NO
  291.  */
  292. boolean ini_get_yesno(char *section, char *section_title, char *option)
  293. {
  294.   char *str;                           // parameter
  295.   word ptr[2];                         // two generic offset pointers
  296.  
  297.   str = ini_verify_format(section, section_title, option, ptr);
  298.  
  299.   str_case_up(str);
  300.   if (!str_cmp(str, "YES"))
  301.     return( TRUE );
  302.   if (str_cmp(str, "NO"))
  303.     ini_get_error(section, str, ptr, BOOLEAN);
  304.   return( FALSE );
  305. }
  306.  
  307. /*----------------------------------------------------------------------------
  308.  * Read in the relevent information of a section.
  309.  *
  310.  * "str1" - string marking the beginning of the section
  311.  * "str2" - string marking the ending of the section
  312.  * "f"    - file handle of file to read from
  313.  *
  314.  * RETURNS:
  315.  * = pointer to buffer containing relevant section information
  316.  */
  317. char *ini_read_section(char *str1, char *str2, FILE *f)
  318. {
  319.   char *section;     // relevent section information (can double as error msg)
  320.   word  size = 1000;                   // default size of text input buffer
  321.  
  322.   if (!fil_skip_to(str1, f)) {
  323.     section = (char *) malloc(1000);   // ample error message space
  324.     sprintf(section, ERR06, str1, str1);
  325.     fprintf(stderr, section);
  326.     free(section);
  327.     beep(); exit(4);
  328.   }
  329.  
  330.   if ((section = fil_read_to_strip(str2, &size, f)) == NULL) {
  331.     section = (char *) malloc(1000);   // ample error message space
  332.     sprintf(section, ERR07, str2);
  333.     fprintf(stderr, section);
  334.     free(section);
  335.     beep(); exit(5);
  336.   }
  337.  
  338.   return( section );                   // return relevent section information
  339. }
  340.  
  341. /*----------------------------------------------------------------------------
  342.  * Verify format of the initialization file.
  343.  * Checks if the - section is present
  344.  *               - option is present
  345.  *               - an equals '=' is present
  346.  *
  347.  * "section"       - section text
  348.  * "section_title" - section title to read from
  349.  * "option"        - option to read from
  350.  * "ptr"           - two offset pointers
  351.  *
  352.  * RETURNS:
  353.  * = pointer to next parameter
  354.  */
  355. char *ini_verify_format(char *section, char *section_title,
  356.                         char *option, word *ptr)
  357. {
  358.   char *param;                         // parameter (can double as error msg)
  359.   word  index1,                        // generic buffer index #1
  360.         index2;                        // generic buffer index #2
  361.  
  362.   // verify the desired section is present
  363.   if (!(ptr[0] = scan_str(section, section_title, NULL, FORWARD))) {
  364.     section[scan_byte(section, LF, NULL, FORWARD)-1] = NULL;
  365.     param = (char *) malloc(1000);     // ample error message space
  366.     sprintf(param, ERR06, section, section_title);     // a section is missing
  367.     fprintf(stderr, param);
  368.     free(param);
  369.     beep(); exit(4);
  370.   }
  371.  
  372.   // get length of this section
  373.   index1 = scan_byte(section+ptr[0], '[', NULL, FORWARD);
  374.  
  375.   // skip past section header
  376.   index2 = scan_byte(section+ptr[0], LF, index1, FORWARD);
  377.   ptr[1] = ptr[0]-1;                   // keep an index to section beginning
  378.   ptr[0] += index2;
  379.  
  380.   // verify the desired option is present
  381.   if (!(index2 = scan_str(section+ptr[0], option, index1-index2, FORWARD))) {
  382.     param = (char *) malloc(1000);     // ample error message space
  383.     sprintf(param, ERR08, section_title, option);      // an option is missing
  384.     fprintf(stderr, param);
  385.     free(param);
  386.     beep(); exit(6);
  387.   }
  388.  
  389.   // get to the offset of the second letter of that option
  390.   ptr[0] += index2;
  391.  
  392.   // search for an equal sign
  393.   index2 = scan_byte(section+ptr[0], '=', NULL, FORWARD);
  394.  
  395.   // make sure the equal sign follows the option in question
  396.   if (index2 != str_len(option)) {
  397.     section[ptr[1]+index1] = NULL;
  398.     param = (char *) malloc(1000);     // ample error message space
  399.     sprintf(param, ERR09, section+ptr[1], option);     // '=' (equals) missing
  400.     fprintf(stderr, param);
  401.     free(param);
  402.     beep(); exit(7);
  403.   }
  404.  
  405.   // get to the offset to the parameter (just beyond the equal sign)
  406.   ptr[0] += index2;
  407.   param = str_next_str(section+ptr[0]);// read in next parameter
  408.   return( param );                     // return next parameter
  409. }
  410.  
  411. /*==============================  END-OF-FILE  =============================*/
  412.